import random
import numpy as np
import pandas as pd
import pyqtgraph as pg
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
from pyqtgraph.exporters import ImageExporter

from src.sharedSrc import getSetting, rHEX


class BinChart(QWidget):
    def __init__(self):
        super().__init__()

        self.text_items = []
        self.plotlayout = pg.GraphicsLayoutWidget()
        self.plotlayout.setBackground('white')  # Set the entire plot area background to white
        self.setLayout(QVBoxLayout())
        self.layout().addWidget(self.plotlayout)
        self.view_list = []
        self.settings = getSetting()

    def setBinData(self, binData: dict, file_name: str = '') -> None:
        row = 0
        for binType in ["HBIN", "SBIN"]:
            hsbin = binData[binType]  # hsbin {0: {1: 26, 3: 61, 4: 57, 5: 286, 9: 15}}
            binTicks = binData[
                binType + "_Ticks"]  # hsbin {0: {1: 26, 3: 50, 9: 15, 200: 1, 201: 2, 202: 8, 300: 2, 310: 13, 311: 1, 320: 2, 330: 12, 340: 2, 350: 1, 360: 4, 362: 1, 370: 1, 410: 18, 500: 39, 700: 5, 800: 18, 1000: 2, 2000: 150, 3000: 55, 4000: 8, 6000: 5, 7000: 2, 8000: 2}}
            isHBIN = True if binType == "HBIN" else False

            num_files = len(hsbin)
            tmpVbList = []
            if isHBIN:
                self.binColor = self.settings.hColor
            else:
                self.binColor = self.settings.sColor

            # binColorDict = settings.hbinColor if isHBIN else settings.sbinColor
            binTypeName = "Hardware Bin" if isHBIN else "Software Bin"
            self.plotlayout.addLabel(f"{binTypeName}",
                                     row=row, col=1,
                                     rowspan=1, colspan=num_files,
                                     size="20pt")
            row += 1
            for fid in hsbin.keys():
                view_bin = pg.ViewBox()
                view_bin.invertY(True)
                pitem = pg.PlotItem(viewBox=view_bin)
                binStats = hsbin[fid]

                numList = binTicks.keys()
                cntList = np.array([binStats.get(n, 0) for n in numList])

                # colorList = [self.binColorDict[0] if n == '1' else self.binColorDict[random.randint(1, 9)] for n in numList]
                colorList = []
                for i in numList:
                    if i in self.binColor:
                        colorList.append(self.binColor[i])
                    else:
                        colorList.append(rHEX())
                y = np.arange(len(numList))
                height = 0.8
                bar = pg.BarGraphItem(x0=0, y=y, width=cntList, height=height, brushes=colorList)
                pitem.addItem(bar)

                # Add text items above bars
                for index, value in enumerate(cntList):
                    text_item = pg.TextItem(text=str(value), color='black', anchor=(0.5, 0.5))
                    text_item.setPos(value+0.25, y[index])
                    pitem.addItem(text_item)

                # Format ticks with labels from binTicks
                ticks = [[binTicks[n] for n in numList]]
                pitem.getAxis("left").setTicks(ticks)
                pitem.getAxis("bottom").setLabel(f"{binType} Count"
                                                 if num_files == 1
                                                 else f"{binType} Count in File {fid}")
                x_max = max(cntList) * 1.15
                y_max = len(numList)
                view_bin.setLimits(xMin=0, xMax=x_max,
                                   yMin=-1, yMax=y_max,
                                   minXRange=2, minYRange=4)
                view_bin.setRange(xRange=(0, x_max),
                                  yRange=(-1, y_max),
                                  disableAutoRange=False)
                self.plotlayout.addItem(pitem, row=row, col=fid, rowspan=1, colspan=1)
                tmpVbList.append(view_bin)
                self.view_list.append(view_bin)
            row += 1
        if file_name != '':
            self.save_plot(file_name)

    def save_plot(self, filename: str) -> None:
        exporter = ImageExporter(self.plotlayout.scene())
        exporter.export(filename)
def bin_summary(df: pd) -> dict:
    """设置bin 总结数据"""
    cate = df[(df['Force'] == 'Cate')].fillna("")
    bin = df[(df['Force'] == 'Bin')].fillna("")

    hBin = dict()
    sBIN = dict()
    HBIN_Ticks = dict()
    SBIN_Ticks = dict()
    cnt1 = 0
    cnt2 = 0
    for i, j in zip(bin, cate):
        b = bin[i].values[0]
        c = cate[j].values[0]
        if b != "" and b != "Bin":
            if b in hBin:
                hBin[b] += 1
            else:
                hBin[b] = 1
                HBIN_Ticks[b] = (cnt1, b)
                cnt1 += 1
        if c != "" and c != "Cate":
            if c in sBIN:
                sBIN[c] += 1
            else:
                sBIN[c] = 1
                SBIN_Ticks[c] = (cnt2, c)
                cnt2 += 1

    bin_data = {
        "HBIN": {1: hBin},
        "SBIN": {1: sBIN},  # Use similar data structure if SBIN is needed
        "HBIN_Ticks": HBIN_Ticks,
        "SBIN_Ticks": SBIN_Ticks  # Use similar data structure if SBIN_Ticks is needed
    }

    return bin_data

if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    bin_chart = BinChart()
    df = pd.read_csv(r"D:\dataset\new\auto_20240709-233354_datalog_20240710070313.csv")

    bin_chart.setBinData(bin_summary(df))
    bin_chart.show()
    sys.exit(app.exec_())
